package com.wanxi.service.Impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.wanxi.dao.ManagerDao;
import com.wanxi.dto.ResultDTO;
import com.wanxi.model.Manager;
import com.wanxi.service.ManagerService;
import com.wanxi.util.CreateOnlyID;
import com.wanxi.util.JSONCopy;
import com.wanxi.util.Md5;
import com.wanxi.util.RedisTool;
import com.wanxi.vo.ManagerVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class ManagerServiceImpl implements ManagerService {
    @Autowired
    ManagerDao managerDao;
    @Autowired
    CreateOnlyID createOnlyID;
    Integer count = 0;

    @Override
    public ResultDTO login(ManagerVO managerVO,String remoteAddr) {
        //获取redis中的验证码
        managerVO.setVCode(RedisTool.getToRedis("vCode"));
        //获取一个账户登录失败次数
        String filedTimes = RedisTool.getToRedis(managerVO.getManagerName());

        filedTimes = filedTimes == null ? "0" : filedTimes;
        //判断账号是否登录失败超过5次，如果超过5次，则冻结5分钟
        if (Integer.parseInt(filedTimes) >= 5) {
            synchronized (count) {
                count = 0;
            }
            return ResultDTO.builder().code(1).msg("该账户已冻结").build();
        }
        //判断验证码是否失效
        if (managerVO.getVCode() == null)
            return ResultDTO.builder().code(-1).msg("验证码已失效").build();
        //判断验证码存在且正确
        if (managerVO.getCode() != null && managerVO.getCode().equals(managerVO.getVCode())) {
            Manager manager = Manager.builder()
                    .managerName(managerVO.getManagerName())
                    .password(Md5.encoderByMd5(managerVO.getPassword()))
                    .build();
            //根据传来的值进行查找
            Manager m = managerDao.findManagerByManagerNameAndPassword(manager);
            //判断账号密码是否正确，是否被禁用
            if (m != null && m.getEnable() != null && m.getEnable() == 1) {
                //登录成功，向redis中写入验证
                RedisTool.setToRedis("loginManager"+remoteAddr, 1800, JSONObject.toJSONString(m));
                addRemoteAddr(remoteAddr);
                deleteRemoteAddr();
                //清除登录失败次数
                RedisTool.deleteToRedis(managerVO.getManagerName());
                synchronized (count) {
                    count = 0;
                }
                return ResultDTO.builder().code(0).msg("success").data(m).count(1).build();
            } else {
                synchronized (count) {
                    //向redis中写入登录失败次数
                    RedisTool.setToRedis(managerVO.getManagerName(), 300, ++count + "");
                }
                //一个用户登录失败的次数
                int times = Integer.parseInt(RedisTool.getToRedis(managerVO.getManagerName()));
                return ResultDTO.builder().code(1)
                        .msg("账号或密码错误,剩余登录次数：" + (5 - times))
                        .data(managerVO).count(0).build();
            }
        } else
            return ResultDTO.builder().msg("验证码错误").code(-1).build();
    }

    @Override
    public ResultDTO findAllManager() {
        List<Manager> list = managerDao.findAllManager();
//        保证密码不泄露
        if (list.size() > 0) {
            list.forEach(manager -> {
                manager.setPassword("******");
            });
            return ResultDTO.getDTO(list.size(), list);
        } else {
            return ResultDTO.builder().count(0).data(list).msg("no data").build();
        }
    }

    @Override
    public ResultDTO findManagerById(ManagerVO managerVO) {
        Manager manager = Manager.builder()
                .id(managerVO.getId())
                .build();
        Manager m = managerDao.findManagerById(manager);
        if (m != null) {
            m.setPassword("******");
            return ResultDTO.getDTO(1, m);
        } else {
            return ResultDTO.builder().count(0).msg("no found").code(1).build();
        }
    }

    @Override
    public ResultDTO addManager(ManagerVO managerVO) {
        Manager manager = Manager.builder()
                .id(createOnlyID.createId())
                .managerName(managerVO.getManagerName())
                .password(Md5.encoderByMd5(managerVO.getPassword()))
                .enable(managerVO.getEnable())
                .remark(managerVO.getRemark())
                .build();
        if (managerVO.getEnable() == null)
            manager.setEnable(0);
        Manager m = managerDao.findManagerByName(manager);
        if (m == null) {
            int i = managerDao.addManager(manager);
            if (i == 1) {
                return ResultDTO.getDTO(i, managerVO);
            }
        }
        return ResultDTO.builder().code(1).count(0).msg("error").data(managerVO).build();
    }

    @Override
    public ResultDTO updatePassword(ManagerVO managerVO) {
        if (managerVO.getOldPassword() != null && !managerVO.getOldPassword().equals("")) {
            Manager manager = Manager.builder()
                    .id(managerVO.getId())
                    .oldPassword(Md5.encoderByMd5(managerVO.getOldPassword()))
                    .newPassword(Md5.encoderByMd5(managerVO.getNewPassword())).build();
            Manager m = managerDao.findManagerByIdAndPassword(manager);
            if (m != null) {
                int i = managerDao.updatePassword(manager);
                if (i == 1) {
                    RedisTool.deleteToRedis("loginManager");
                    return ResultDTO.getDTO(i, managerVO);
                }
            }
            return ResultDTO.builder().msg("原密码错误").count(0).code(1).data(managerVO).build();
        }
        return ResultDTO.builder().msg("error").count(0).code(1).data(managerVO).build();
    }

    @Override
    public ResultDTO deleteManager(ManagerVO managerVO) {
        Manager manager = Manager.builder().id(managerVO.getId()).build();
        int i = managerDao.deleteManager(manager);
        if (i == 1) {
            return ResultDTO.getDTO(i, managerVO);
        }
        return ResultDTO.builder().count(0).data(managerVO).code(1).msg("error").build();
    }

    @Override
    public ResultDTO updateById(ManagerVO managerVO) {
        Manager manager = new Manager();
        manager.setId(managerVO.getId());
        manager.setManagerName(managerVO.getManagerName());
        manager.setRemark(managerVO.getRemark());
        if (managerVO.getId() != null) {
            Manager m = managerDao.findManagerById(manager);
//            密码处理
            if (managerVO.getPassword() != null && managerVO.getPassword().equals("1")) {
                manager.setPassword(Md5.encoderByMd5(null));
            } else if (managerVO.getPassword() == null || managerVO.getPassword().equals("0")) {
                manager.setPassword(m.getPassword());
            }
//            状态处理
            if (managerVO.getEnable() == null)
                manager.setEnable(m.getEnable());
            else
                manager.setEnable(managerVO.getEnable());
//            用户名处理
            if (managerVO.getManagerName() == null)
                manager.setManagerName(m.getManagerName());

            int i = managerDao.updateById(manager);
            if (i == 1) {
                return ResultDTO.getDTO(i, managerVO);
            }
        }
        return ResultDTO.builder().msg("error").code(1).count(0).data(managerVO).build();
    }

    @Override
    public ResultDTO updateEnable(ManagerVO managerVO) {
        Manager manager = Manager.builder().id(managerVO.getId()).enable(managerVO.getEnable()).build();
        if (managerVO.getEnable() == null) {
            manager.setEnable(0);
        }
        int i = managerDao.updateEnable(manager);
        if (i == 1) {
            return ResultDTO.getDTO(i, managerVO);
        }
        return ResultDTO.builder().data(managerVO).count(0).code(1).msg("error").build();
    }

    @Override
    public ResultDTO findManagerBySome(ManagerVO managerVO) {
        Manager manager = JSONCopy.copy(managerVO, Manager.class);
        List<Manager> list = managerDao.findBySome(manager);
//        保证密码不泄露
        if (list.size() > 0) {
            list.forEach(m -> {
                m.setPassword("******");
            });
            return ResultDTO.getDTO(list.size(), list);
        } else {
            return ResultDTO.builder().count(0).data(list).msg("no data").build();
        }
    }

    private void deleteRemoteAddr() {
        String redisIp=RedisTool.findToRedis("ip").toString();
        List<String> ips = JSON.parseObject(redisIp, new TypeReference<List<String>>() {});
        System.out.println(redisIp);
        if(ips.size()>5){
            RedisTool.popToRedis("ip");
        }
    }

    private void addRemoteAddr(String remoteAddr) {
        List<String> ip = RedisTool.findToRedis("ip");
        if(ip!=null){
            List<String> ips = JSON.parseObject(ip.toString(), new TypeReference<List<String>>() {});
            if(!ips.contains(remoteAddr)){
                RedisTool.putListToRedis("ip",1800,JSONObject.toJSONString(remoteAddr));
            }
        }

    }
}
